/*
 * ElementStep.java
 *
 * Created on February 2, 2007, 8:13 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package com.smallx.xpath.streaming;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.infoset.xml.Item;
import org.infoset.xml.ItemDestination;
import org.infoset.xml.Named;
import org.infoset.xml.XMLException;

/**
 *
 * @author alex
 */
public class ElementStep extends NamedStep {

   static Logger LOG = Logger.getLogger(ElementStep.class.getName());
   static {
      LOG.setUseParentHandlers(true);
   }
   int level;
   boolean isFineLog;
   boolean lastMatch;
   /** Creates a new instance of ElementStep */
   public ElementStep() {
      level = -1;
      isFineLog = LOG.isLoggable(Level.FINE);
   }
   
   public void attach(final ItemDestination nextStep) {
      if (nextStep instanceof ElementStep || nextStep instanceof DescendantsStep) {
         Step step = new Step(this) {
            int level = -1;

            public void notifyNotMatching() {
               level = lastMatch ? 0 : -1;
               ElementStep.this.notifyNotMatching();
            }

            public void send(Item item) 
               throws XMLException
            {
               switch (item.getType()) {
                  case ElementItem:
                     level++;
                     if (level>0) {
                        post(item);
                     }
                     break;
                  case ElementEndItem:
                     if (level>0) {
                        post(item);
                     }
                     level--;
                     break;
                  default:
                     if (level>=0) {
                        post(item);
                     }
               }
            }
         };
         step.attach(nextStep);
         super.attach(step);
      } else {
         super.attach(nextStep);
      }
   }
   
   public void notifyNotMatching() {
      level = lastMatch ? 0 : -1;
   }
   
   public void send(Item item)
      throws XMLException
   {
      lastMatch = item.getType()==Item.ItemType.ElementItem && match(item) && testPredicates(item,null);
      if (level<0) {
         if (lastMatch) {
            if (isFineLog) {
               LOG.fine("Element match for: "+((Named)item).getName());
            }
            level = 0;
            post(item);
         }
      } else {
         switch (item.getType()) {
            case ElementItem:
               level++;
               break;
            case ElementEndItem:
               level--;
         }
         post(item);
      }
   }
   
   
}
